缘由
- 使用Hash Mode开发的一套大系统,完全成型
- 由于各种跳转的问题,nginx的转发会导致#后面的路径丢失
- 想试试History Mode
- 环境 Vue-Cli 早期版本,webpack 2.6
相关配置
基础配置
- 将Vue Router mode设置为history,并将跳转路径中带#的
hash
路由改为history
对应的方式 - webpack-dev-middleware 不带
dev-server
相关内容,只处理内容的映射,需要配合connect-history-api-fallback来做,默认给了一个默认的映射,但多级路由页面刷新还是会出现404
historyApiFallback日志
配置connect-history-api-fallback
1
2
3
4// handle fallback for HTML5 history http
app.use(require('connect-history-api-fallback')({
verbose:true //开启日志信息
}))本地路由404
即使配置了这样的情况,还是会出现路由点击跳转好使,刷新页面404的情况,原因是刷新页面的地址被
proxyTable
匹配到了,找去了服务端(因为ProxyMiddleware
在connect-history-api-fallback
中间件前面),没有走Fallback,解决办法是把所有服务相关的转发都加上api后缀或者使用connect-history-api-fallback
的rewrites
配置来做,前提是中间件的加载位置要在代理中间件前面。
本地图片404
- 原有图片是直接在Vue组件里面利用相对路径写的,对于history模式来说,总会根据当前路径加上莫须有的前缀,这里直接将所有图片路径写上绝对路径就好了
/static/xxx
Web Server 路由404
将打包后的内容部署到Web Server根目录,刷新页面路由会出现404,根据Vue Router官网文档配置 Web Server即可解决相关问题,比如nginx 配置,就会再找不到的情况下转到 index.html 通过router 解析路由
1
2
3location / {
try_files $uri $uri/ /index.html;
}然而,更多时候我们的应用不是部署在根目录的,而是在某个路径下比如 app-test,这个时候最好的方式是我们引用的资源路径都跟着走相对路径,打包出来自带光环,但看看前面图片路径的情况则不尽然。这个时候我们加载相关页面各种图片资源404,刷新页面路由会报500,上面的nginx转发规则已经不适用了。
Web Server 路由500
- 上面官方文档里面的nginx配置已经不适合带路径目录的项目了,需要干掉。
应用增加base /app-test/
路由首先加上一个base ,这样路由跳转的时候才不会越界
1
2
3
4
5export default new Router({
mode:'history',
base:'/app-test/',
routes
})build.assetsPublicPath 值改为
/app-test/
,这样打包路径相关的资源会加上这个前缀dev.assetsPublicPath 值改为
/app-test/
,这样本地dev server 路径能跟服务端访问一致配置本地Server 转发
1
2
3
4
5// handle fallback for HTML5 history http
app.use(require('connect-history-api-fallback')({
verbose:true,
index:'/app-test/index.html',
}))Vue组件模板中使用
@/../static/images/xxx.png
引用图片, 其中@
为src
的别名 参考 vue-loaderVue组件中SCSS style 使用
~/../static/images/xxx.png
引用图片,其中~
使后面的解析为模块路径,~@/
代表src
参考 sass-loader 或者 css-loader 或者 vue cli在 js 中使用的话,按相对于
src
的路径写,import
或者require
都ok,对应nginx配置需要改为
1
2
3location /app-test {
try_files $uri $uri/ /app-test/index.html;
}实例代码在 这 github
相对路径适配问题
上面增加base的情况适用于固定的部署方式,换个路径需要改代码重新打包,我们希望有一种方式自动适配路径,改到什么路径改改ng配置就行,代码不用动
首先修改
config/index.js
中的路径为相对路径1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23@@ -9,7 +9,7 @@ module.exports = {
// Paths
assetsSubDirectory: 'static',
- assetsPublicPath: '/app-test/',
+ assetsPublicPath: './',
proxyTable: {},
// Various Dev Server settings
@@ -45,12 +45,12 @@ module.exports = {
build: {
// Template for index.html
- index: path.resolve(__dirname, '../app-test/index.html'),
+ index: path.resolve(__dirname, '../dist/index.html'),
// Paths
- assetsRoot: path.resolve(__dirname, '../app-test'),
+ assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
- assetsPublicPath: '/app-test/',
+ assetsPublicPath: './',然后修改
build/utils.js
调整css 抽取的路径1
2
3
4
5
6
7return ExtractTextPlugin.extract({
use: loaders,
fallback: 'vue-style-loader'
fallback: 'vue-style-loader',
+ publicPath:'../../'
})最后调整下
src/router/index.js
动态获取路由,这里面加了个标识,是为了解决目录名和路由名分不开的问题,比如/path/to/dir/dist/path/to/router
, 就用中间这个dist
来区分出那部分是部署的目录名哪部分是路由路径1
2
3
4
5
6
7
8
9
10
11+const identifier = 'dist/'
+const getBasePath = () => {
+ const path = location.pathname
+ return path.substr(0, path.lastIndexOf(identifier) + identifier.length)
+}
+
export default new Router({
mode: 'history',
- base: '/app-test/',
+ base: getBasePath(),
参考资料
[
]
最后更新: 2022年03月02日 03:32
原始链接: http://rawbin-.github.io/framework/vue/2017-10-05-vue-router-history-mode/